home *** CD-ROM | disk | FTP | other *** search
- { ======================================================================
- Here are a couple of handy Turbo Pascal 6.0 assembler routines
- for fast string operations. Simply include them in your source
- code. The built-in Turbo Pascal 6.0 assembler takes care of the
- rest.
-
- Author: Keith Greer
- 68 Tamworth Rd.
- Troy, OH 45373
-
- ========================================================================}
-
-
-
- { SpaceOut removes leading blanks from AnyString and returns the
- resulting string. For example:
-
- SpaceOut(' My String') = 'My String'
-
- Compared to its comparable pascal version:
-
- ---------------------------------------------------
- function SpaceOut(AnyString : string) : string;
- var
- i,l : integer;
-
- begin
- i:=1; l:=Length(AnyString);
- while (i<l) and (AnyString[i]=' ') do Inc(i);
- if i>l then SpaceOut:='' else
- SpaceOut:=Copy(AnyString,i,l-i+1);
- end;
- ---------------------------------------------------
- this assembler version is over twice as fast, and about 80 bytes
- smaller in generated code size.
-
- }
-
- function SpaceOut(AnyString:string) :string; assembler;
- asm
- PUSH DS {Save Data Segment}
- CLD {Clear direction flag}
- LES DI,AnyString {ES:DI-->AnyString}
- MOV AL,ES:[DI] {Get the length of AnyString}
- CBW {Make it a word}
- MOV CX,AX
- JCXZ @1 {AnyString was ''!}
- INC DI {ES:DI-->First char of AnyString}
- MOV DX,DI {DX has first char offset}
- ADD DX,AX {Add the length}
- MOV AL,' ' {What to look for}
- REPE SCASB {Keep looking till out of spaces or string}
- JE @1 {Had a string full of spaces, jump}
- DEC DI {Move back to the first non-blank}
- MOV SI,DI {and put the offset into SI}
- PUSH ES
- POP DS {DS:SI-->First non-blank in AnyString}
- MOV AX,DX {AX has offset of last char+1}
- SUB AX,SI {minus current offset is length of Result}
- LES DI,@Result {ES:DI-->Result}
- STOSB {Save the length into Result}
- MOV CX,AX
- REP MOVSB {Get the remainder of AnyString into Result}
- JMP @2 {All done}
- @1:
- LES DI,@Result
- MOV BYTE PTR ES:[DI],0 {Make Result=''}
- @2: {Go back}
- POP DS {Restore Data Segment}
- end;
-
- {=======================================================================}
-
- { FixLen has a little more practical utility. It takes AnyString, and
- pads (or truncates) it with any character to length FldSize. Aside
- from the obvious use of adding blanks to a string to make it a certain
- size, FixLen can also be used to repeat a series characters. For
- example, to draw a 70-character line using the "=" character:
-
- WriteLn(FixLen('','=',70));
-
- }
-
- function FixLen(AnyString:string; PadChar: char; FldSize:word) :string;
- assembler;
- asm
- PUSH DS {Save Data Segment}
- CLD {Clear direction flag}
- LDS SI,AnyString {DS:SI-->AnyString}
- LES DI,@Result {ES:DI-->String to be returned}
- MOV BX,DI {Save DI value for later}
- LODSB {AL has Length(AnyString)}
- CBW {Make AL into word in AX}
- STOSB {Put the length into Result & Inc(DI)}
- MOV CX,AX {Length in CX}
- REP MOVSB {Pad=AnyString}
- MOV CX,FldSize {CX has FldSize}
- XOR CH,CH {Make FldSize=FldSize mod 256}
- MOV ES:[BX],CL {Make Length(Pad)=FldSize}
- SUB CX,AX {CX=FldSize-Length(AnyString)}
- JB @1 {Return truncated string if CX<0}
- MOV AL,PadChar {else load character to pad}
- REP STOSB {and pad to FldSize}
- @1: {Go back}
- POP DS {Restore Data Segment}
- end;
-
-
-